home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1996 / MacHack 1996.toast / Hacks / Hacks '96 / Internet Chooser / reggie / light / mactcp.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-06-22  |  21.9 KB  |  742 lines  |  [TEXT/MMCC]

  1. /* File "mactcp.cpp", Light Sockets - Copyright (C) Matt Slot, 1996           */
  2. /* MacTCP implementation for "Light Sockets" network abstraction library.     */
  3.  
  4. #include <A4Stuff.h>
  5. #include <AddressXlation.h>
  6. #include <LowMem.h>
  7. #include <MacTCP.h>
  8. #include <string.h>
  9.  
  10. #include "stddebug.h"
  11. #include "stdmacro.h"
  12. #include "stdtypes.h"
  13.  
  14. #include "my mactcp.h"
  15. #include "patches.h"
  16.  
  17. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  18. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  19. /* Global/Static Data */
  20.  
  21. UInt32 MacTCPStack::loadCount = 0;
  22.  
  23. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  24. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  25.  
  26. MacTCPStack::MacTCPStack(SocketRef socket) : NetworkStack(socket) {
  27.     refnum = 0;
  28.     stream = 0;
  29.     disposing = false;
  30.     readUPP = 0;
  31.     bfrRtnUPP = 0;
  32.     sendDoneUPP = 0;
  33.     freeQ.qHead = freeQ.qTail = 0;
  34.     busyQ.qHead = busyQ.qTail = 0;
  35.     }
  36.  
  37. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  38. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  39.  
  40. MacTCPStack::~MacTCPStack() {
  41.     DoDispose();
  42.     }
  43.  
  44. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  45. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  46. #pragma mark -
  47.  
  48. SocketResult MacTCPStack::DoLoad() {
  49.     SocketResult error = eSocketNoError;
  50.     
  51.     /* Implement socket callback chain */
  52.     qThrowIfError(NetworkStack::DoLoad(), 0);
  53.  
  54.     if (! loadCount) {
  55.         /* Load the "first" network stack */
  56.         
  57.         /* Open MacTCP only if it hasn't been loaded before */
  58.         if (! refnum)
  59.             qThrowIfError(OpenDriver("\p.ipp", &refnum),
  60.                     "Error opening MacTCP");
  61.         }
  62.     loadCount++;
  63.     
  64. /* CATCH */
  65.     qCatch();
  66.     return(error);
  67.     }
  68.  
  69. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  70. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  71.  
  72. SocketResult MacTCPStack::DoUnload() {
  73.     SocketResult error = eSocketNoError;
  74.     
  75.     /* Parameter validation */
  76.     qAssertIfFalse(refnum, eSocketErrNotLoaded, kSocketErrNotLoadedStr);
  77.  
  78.     loadCount--;
  79.     if (! loadCount) {
  80.         /* Unload the "last" network stack */
  81.         
  82.         /* Normally we would close the network stack, but you don't do that
  83.            for MacTCP. So just sit tight and let the call complete. */
  84.         
  85.         }
  86.  
  87.     /* Implement socket callback chain */
  88.     qThrowIfError(NetworkStack::DoUnload(), 0);
  89.     
  90. /* CATCH */
  91.     qCatch();
  92.     return(error);
  93.     }
  94.  
  95. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  96. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  97. #pragma mark -
  98.  
  99. SocketResult MacTCPStack::DoCreate() {
  100.     SocketResult error = eSocketNoError;
  101.     
  102.     /* Parameter validation */
  103.     qAssertIfFalse(refnum, eSocketErrNotLoaded, kSocketErrNotLoadedStr);
  104.  
  105.     /* Implement socket callback chain */
  106.     qThrowIfError(NetworkStack::DoCreate(), 0);
  107.  
  108. #if GENERATINGCFM || __A5__
  109.     homeA5 = (UInt32) LMGetCurrentA5();
  110. #else
  111.     homeA4 = GetCurrentA4();
  112. #endif
  113.  
  114.     InstallE2STask((E2STaskProc) E2SCleanup, this);
  115.  
  116.     if (qIsSocketTypeUDP(socket->GetSocketType())) {
  117.         UInt32 i;
  118.         
  119.         for(i=0; i<kMacTCPNumParamBlocks; i++)
  120.             Enqueue((QElemPtr) dataBuffs+i, &freeQ);
  121.  
  122.         /* UDPCreate occurs in DoBind() */
  123.         }
  124.       else if (qIsSocketTypeRawIP(socket->GetSocketType())) {
  125.         qThrowErr(eSocketErrNoSupport, kSocketErrNoSupportStr);
  126.         }
  127.       else if (qIsSocketTypeTCP(socket->GetSocketType())) {
  128.         qThrowErr(eSocketErrNoSupport, kSocketErrNoSupportStr);
  129.         }
  130. //      else qThrowErr(eSocketErrBadParam, kSocketErrBadParamStr);
  131.  
  132.  
  133. /* CATCH */
  134.     qCatch();
  135.     return(error);
  136.     }
  137.  
  138. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  139. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  140.  
  141. SocketResult MacTCPStack::DoTickle() {
  142.     SocketResult error = eSocketNoError;
  143.     
  144.     /* Implement socket callback chain */
  145.     qThrowIfError(NetworkStack::DoTickle(), 0);
  146.  
  147.  
  148. /* CATCH */
  149.     qCatch();
  150.     return(error);
  151.     }
  152.  
  153. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  154. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  155.  
  156. SocketResult MacTCPStack::DoDispose() {
  157.     SocketResult error = eSocketNoError;
  158.     
  159.     /* Parameter validation */
  160.     qAssertIfFalse(refnum, eSocketErrNotLoaded, kSocketErrNotLoadedStr);
  161.  
  162.     disposing = true;
  163.     RemoveE2STask((E2STaskProc) E2SCleanup, this);
  164.  
  165.     if (socket) {
  166.         /* In MacTCP, UDP/TCP release acts as an Unbind */
  167.         if (qIsSocketTypeUDP(socket->GetSocketType())) {
  168.             if (stream) {
  169.                 UDPiopb    udppb;
  170.                 
  171.                 /* Due to the design of MacTCP, there is no way to cancel an
  172.                    outstanding UDPWrite or to release until they have completed.
  173.                    This is where we sit and spin until that happens. */
  174.                 while(busyQ.qHead)
  175.                     socket->Tickle();
  176.                 
  177.                 udppb.ioCompletion = 0;
  178.                 udppb.ioResult = 0;
  179.                 udppb.ioCRefNum = refnum;
  180.                 udppb.csCode = UDPRelease;
  181.                 udppb.udpStream = stream;
  182.                 udppb.csParam.create.rcvBuff = 0;
  183.                 udppb.csParam.create.rcvBuffLen = 0;
  184.                 udppb.csParam.create.userDataPtr = (Ptr) this;
  185.                 qTraceIfError(PBControlSync((ParmBlkPtr) &udppb), 
  186.                         "Unable to Release UDP Stream");
  187.                 
  188.                 stream = 0;
  189.                 }
  190.                 
  191.             if (readUPP) {
  192.                 DisposeRoutineDescriptor(readUPP);
  193.                 readUPP = 0;
  194.                 }
  195.             if (bfrRtnUPP) {
  196.                 DisposeRoutineDescriptor(bfrRtnUPP);
  197.                 bfrRtnUPP = 0;
  198.                 }
  199.             if (sendDoneUPP) {
  200.                 DisposeRoutineDescriptor(sendDoneUPP);
  201.                 sendDoneUPP = 0;
  202.                 }
  203.             }
  204.           else if (qIsSocketTypeRawIP(socket->GetSocketType())) {
  205.             qThrowErr(eSocketErrNoSupport, kSocketErrNoSupportStr);
  206.             }
  207.           else if (qIsSocketTypeTCP(socket->GetSocketType())) {
  208.             qThrowErr(eSocketErrNoSupport, kSocketErrNoSupportStr);
  209.             }
  210.           else qThrowErr(eSocketErrBadParam, kSocketErrBadParamStr);
  211.         }
  212.         
  213.     /* Implement socket callback chain */
  214.     qThrowIfError(NetworkStack::DoDispose(), 0);
  215.  
  216. /* CATCH */
  217.     qCatch();
  218.     return(error);
  219.     }
  220.  
  221. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  222. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  223. #pragma mark -
  224.  
  225. SocketResult MacTCPStack::DoBind(SocketAddressPtr reqAddress,
  226.         SocketAddressPtr retAddress) {
  227.     SocketResult error = eSocketNoError;
  228.     UInt16 savePort = 0;
  229.     
  230.     /* Parameter validation */
  231.     qAssertIfFalse(refnum, eSocketErrNotLoaded, kSocketErrNotLoadedStr);
  232.     qAssertIfTrue(stream, eSocketErrWasBound, kSocketErrWasBoundStr);
  233.  
  234.     /* Implement socket callback chain */
  235.     qThrowIfError(NetworkStack::DoBind(reqAddress, retAddress), 0);
  236.  
  237.  
  238.     /* In MacTCP, UDP/TCP Create actually do the Bind */
  239.     if (qIsSocketTypeUDP(socket->GetSocketType())) {
  240.         UDPiopb    udppb;
  241.         
  242.         qThrowIfNull(readUPP = NewUDPIOCompletionProc(UDPAsyncRead),
  243.                 eSocketErrOutOfMem, kSocketErrOutOfMemStr);
  244.         qThrowIfNull(bfrRtnUPP = NewUDPIOCompletionProc(UDPAsyncBfrRtn),
  245.                 eSocketErrOutOfMem, kSocketErrOutOfMemStr);
  246.         qThrowIfNull(sendDoneUPP = NewUDPIOCompletionProc(UDPSendComplete),
  247.                 eSocketErrOutOfMem, kSocketErrOutOfMemStr);
  248.         
  249.         udppb.ioCompletion = 0;
  250.         udppb.ioResult = 0;
  251.         udppb.ioCRefNum = refnum;
  252.         udppb.csCode = UDPCreate;
  253.         udppb.udpStream = 0;
  254.         udppb.csParam.create.rcvBuff = (Ptr) buffer;
  255.         udppb.csParam.create.rcvBuffLen = sizeof(buffer);
  256.         udppb.csParam.create.notifyProc = 0;
  257.         udppb.csParam.create.localPort = 
  258.                 (reqAddress) ? reqAddress->buffer.tcpip.port : 0;
  259.         udppb.csParam.create.userDataPtr = (Ptr) this;
  260.         qThrowIfError(PBControlSync((ParmBlkPtr) &udppb), 
  261.                 "Unable to Create UDP Stream");
  262.         
  263.         stream = udppb.udpStream;
  264.         savePort = udppb.csParam.create.localPort;
  265.         }
  266.       else if (qIsSocketTypeRawIP(socket->GetSocketType())) {
  267.         qThrowErr(eSocketErrNoSupport, kSocketErrNoSupportStr);
  268.         }
  269.       else if (qIsSocketTypeTCP(socket->GetSocketType())) {
  270.         qThrowErr(eSocketErrNoSupport, kSocketErrNoSupportStr);
  271.         }
  272.       else qThrowErr(eSocketErrBadParam, kSocketErrBadParamStr);
  273.  
  274.     if (retAddress) {
  275.         GetAddrParamBlock addrpb;
  276.     
  277.         addrpb.ioCompletion = 0;
  278.         addrpb.ioResult = 0;
  279.         addrpb.ioCRefNum = refnum;
  280.         addrpb.csCode = ipctlGetAddr;
  281.         addrpb.ourAddress = 0;
  282.         addrpb.ourNetMask = 0;
  283.         qThrowIfError(PBControlSync((ParmBlkPtr) &addrpb), 
  284.                 "Unable to get Local IP Address");
  285.     
  286.         retAddress->type = socket->GetSocketType();
  287.         retAddress->length = sizeof(retAddress->buffer.tcpip);
  288.         retAddress->buffer.tcpip.type = AF_INET;
  289.         retAddress->buffer.tcpip.port = savePort;
  290.         retAddress->buffer.tcpip.host = addrpb.ourAddress;
  291.         memset(retAddress->buffer.tcpip.data, 0,
  292.                 sizeof(retAddress->buffer.tcpip.data));
  293.         }
  294.  
  295.     /* Start any outstanding reads now that the return address is set */
  296.     if (qIsSocketTypeUDP(socket->GetSocketType())) {
  297.         readPB.ioResult = 0;
  298.         readPB.csParam.receive.userDataPtr = (Ptr) this;
  299.         UDPAsyncRead(&readPB);
  300.         }
  301.       else if (qIsSocketTypeRawIP(socket->GetSocketType())) {
  302.         qThrowErr(eSocketErrNoSupport, kSocketErrNoSupportStr);
  303.         }
  304.       else if (qIsSocketTypeTCP(socket->GetSocketType())) {
  305.         qThrowErr(eSocketErrNoSupport, kSocketErrNoSupportStr);
  306.         }
  307.       else qThrowErr(eSocketErrBadParam, kSocketErrBadParamStr);
  308.  
  309.  
  310. /* CATCH */
  311.     qCatch();
  312.     return(error);
  313.     }
  314.  
  315. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  316. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  317.  
  318. SocketResult MacTCPStack::DoUnbind(void) {
  319.     SocketResult error = eSocketNoError;
  320.     
  321.     /* Parameter validation */
  322.     qAssertIfFalse(refnum, eSocketErrNotLoaded, kSocketErrNotLoadedStr);
  323.  
  324.     if (qIsSocketTypeUDP(socket->GetSocketType())) {
  325.         /* UDPRelease occurs in DoDispose(), which can sit and Spin() */
  326.         }
  327.       else if (qIsSocketTypeRawIP(socket->GetSocketType())) {
  328.         qThrowErr(eSocketErrNoSupport, kSocketErrNoSupportStr);
  329.         }
  330.       else if (qIsSocketTypeTCP(socket->GetSocketType())) {
  331.         qThrowErr(eSocketErrNoSupport, kSocketErrNoSupportStr);
  332.         }
  333.       else qThrowErr(eSocketErrBadParam, kSocketErrBadParamStr);
  334.  
  335.     /* Implement socket callback chain */
  336.     qThrowIfError(NetworkStack::DoUnbind(), 0);
  337.  
  338.  
  339. /* CATCH */
  340.     qCatch();
  341.     return(error);
  342.     }
  343.  
  344. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  345. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  346. #pragma mark -
  347.  
  348. SocketResult MacTCPStack::DoAddressResolve(Char8 *textAddress,
  349.         SocketAddressPtr socketAddress) {
  350.     SocketResult error = eSocketNoError;
  351.     Bool8 opened = false;
  352.     Bool8 completed = false;
  353.     hostInfo hInfo;
  354. #if !GENERATINGCFM
  355.     ResultUPP resultUPP = (ResultUPP) DNRComplete;
  356. #else
  357.     RoutineDescriptor xRD = BUILD_ROUTINE_DESCRIPTOR(uppResultProcInfo, DNRComplete);
  358.     ResultUPP resultUPP = (ResultUPP) &xRD;
  359.     
  360.     MakeDataExecutable(&xRD, sizeof(xRD));
  361. #endif
  362.  
  363.     /* Parameter validation */
  364.     qAssertIfFalse(refnum, eSocketErrNotLoaded, kSocketErrNotLoadedStr);
  365.     qAssertIfNull(socketAddress, eSocketErrBadParam, kSocketErrBadParamStr);
  366.     qAssertIfNull(textAddress, eSocketErrBadParam, kSocketErrBadParamStr);
  367.  
  368.     /* Perform the task */
  369.     qThrowIfError(OpenResolver(0), "Error opening DNR");
  370.     opened = true;
  371.     
  372.     error = StrToAddr(textAddress, &hInfo, resultUPP, (Ptr) &completed);
  373.     if (error == cacheFault) {
  374.         error = eSocketNoError;
  375.         qTraceIfError(DoTickle(), 0);
  376.         while(! completed) DoTickle();
  377.         qThrowIfError(hInfo.rtnCode, "Error resolving hostname");
  378.         }
  379.       else qThrowIfError(error, "Error resolving hostname");
  380.     
  381.     socketAddress->type = eSocketTypeUDP; /* For a guess */
  382.     socketAddress->length = sizeof(socketAddress->buffer.tcpip);
  383.     socketAddress->buffer.tcpip.type = AF_INET;
  384.     socketAddress->buffer.tcpip.port = 0;
  385.     socketAddress->buffer.tcpip.host = hInfo.addr[0];
  386.     memset(socketAddress->buffer.tcpip.data, 0, 
  387.             sizeof(socketAddress->buffer.tcpip.data));
  388.     
  389. /* CATCH */
  390.     qCatch();
  391.  
  392.     if (opened)
  393.         qTraceIfError(CloseResolver(), "Error closing DNR");
  394.  
  395.     return(error);
  396.     }
  397.  
  398. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  399. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  400.  
  401. SocketResult MacTCPStack::DoAddressLookup(SocketAddressPtr socketAddress,
  402.         Char8 *textAddress) {
  403.     SocketResult error = eSocketNoError;
  404.     Bool8 opened = false;
  405.     Bool8 completed = false;
  406.     hostInfo hInfo;
  407. #if !GENERATINGCFM
  408.     ResultUPP resultUPP = (ResultUPP) DNRComplete;
  409. #else
  410.     RoutineDescriptor xRD = BUILD_ROUTINE_DESCRIPTOR(uppResultProcInfo, DNRComplete);
  411.     ResultUPP resultUPP = (ResultUPP) &xRD;
  412.     
  413.     MakeDataExecutable(&xRD, sizeof(xRD));
  414. #endif
  415.  
  416.     /* Parameter validation */
  417.     qAssertIfFalse(refnum, eSocketErrNotLoaded, kSocketErrNotLoadedStr);
  418.     qAssertIfNull(socketAddress, eSocketErrBadParam, kSocketErrBadParamStr);
  419.     qAssertIfNull(textAddress, eSocketErrBadParam, kSocketErrBadParamStr);
  420.  
  421.     /* Perform the task */
  422.     qThrowIfError(OpenResolver(0), "Error opening DNR");
  423.     opened = true;
  424.     
  425.     error = AddrToName(socketAddress->buffer.tcpip.host, &hInfo, 
  426.             resultUPP, (Ptr) &completed);
  427.     if (error == cacheFault) {
  428.         error = eSocketNoError;
  429.         qTraceIfError(DoTickle(), 0);
  430.         while(! completed) DoTickle();
  431.         qThrowIfError(hInfo.rtnCode, "Error looking up hostname");
  432.         strcpy(textAddress, hInfo.cname);
  433.  
  434.         /* MacTCP returns hostnames with a trailing '.' -- clip it */
  435.         if (*textAddress && textAddress[strlen(textAddress)-1] == '.')
  436.             textAddress[strlen(textAddress)-1] = 0;
  437.         }
  438.       else qThrowIfError(error, "Error looking up hostname");
  439.  
  440.     
  441. /* CATCH */
  442.     qCatch();
  443.  
  444.     if (error && textAddress) *textAddress = 0;
  445.     if (opened) qTraceIfError(CloseResolver(), "Error closing DNR");
  446.     return(error);
  447.     }
  448.  
  449. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  450. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  451. #pragma mark -
  452.  
  453. SocketResult MacTCPStack::DoDatagramWrite(Byte8 *dataPtr, UInt32 dataLen,
  454.         SocketAddressPtr address) {
  455.     SocketResult error = eSocketNoError;
  456.     MacTCPDataPtr writeData;
  457.     
  458.     /* Parameter validation */
  459.     qAssertIfFalse(refnum, eSocketErrNotLoaded, kSocketErrNotLoadedStr);
  460.     qThrowIfTrue(disposing, eSocketErrInternal, 
  461.             "Can't Send on a Closing socket");
  462.  
  463.     /* Pop off a new container */
  464.     qThrowIfNull(writeData = (MacTCPDataPtr) freeQ.qHead, eSocketErrFlooded, 
  465.             "Too many outstanding writes");
  466.     qThrowIfError(Dequeue((QElem *) writeData, &freeQ),
  467.             "Unable to extract write buffer");
  468.     
  469.     BlockMoveData(dataPtr, writeData->dataBuff, dataLen);
  470.     writeData->wds[0].length = writeData->dataLen = dataLen;
  471.     writeData->wds[0].ptr = (Ptr) writeData->dataBuff;
  472.     writeData->wds[1].length = 0;
  473.     
  474.     /* Make the UDP Write */
  475.     writeData->pb.udppb.ioCompletion = sendDoneUPP;
  476.     writeData->pb.udppb.ioCRefNum = refnum;
  477.     writeData->pb.udppb.csCode = UDPWrite;
  478.     writeData->pb.udppb.udpStream = stream;
  479.     writeData->pb.udppb.csParam.send.reserved = 0;
  480.     writeData->pb.udppb.csParam.send.remoteHost = address->buffer.tcpip.host;
  481.     writeData->pb.udppb.csParam.send.remotePort = address->buffer.tcpip.port;
  482.     writeData->pb.udppb.csParam.send.wdsPtr = (Ptr) writeData->wds;
  483.     writeData->pb.udppb.csParam.send.checkSum = false;
  484.     writeData->pb.udppb.csParam.send.filler = 0;
  485.     writeData->pb.udppb.csParam.send.sendLength = writeData->dataLen;
  486.     writeData->pb.udppb.csParam.send.userDataPtr = (Ptr) this;
  487.     writeData->pb.udppb.csParam.send.localPort = 0;
  488.     
  489.     qEnqueue((QElem *) writeData, &busyQ);
  490.     if (error = PBControlAsync((ParmBlkPtr) &writeData->pb.udppb)) {
  491. #if (_DEBUGSAFE)
  492.         qThrowIfError(error, "Unable to Send on UDP Stream");
  493.         qThrowIfError(Dequeue((QElem *) writeData, &busyQ),
  494.                 "Unable to restore write buffer");
  495. #else
  496.         Dequeue((QElem *) writeData, &busyQ);
  497. #endif
  498.         qEnqueue((QElem *) writeData, &freeQ);
  499.         }
  500.  
  501.     /* Implement socket callback chain */
  502.     qThrowIfError(NetworkStack::DoDatagramWrite(dataPtr, dataLen, address), 0);
  503.  
  504.  
  505. /* CATCH */
  506.     qCatch();
  507.     return(error);
  508.     }
  509.  
  510. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  511. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  512. #pragma mark -
  513.  
  514. SocketResult MacTCPStack::DoStreamServer(UInt32 sessions) {
  515.     return(eSocketErrNoSupport); /* Function not supported yet */
  516.     }
  517.  
  518. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  519. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  520.  
  521. SocketResult MacTCPStack::DoStreamClient(SocketAddressPtr address) {
  522.     return(eSocketErrNoSupport); /* Function not supported yet */
  523.     }
  524.  
  525. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  526. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  527.  
  528. SocketResult MacTCPStack::DoStreamWrite(Byte8 *dataPtr, UInt32 dataLen) {
  529.     return(eSocketErrNoSupport); /* Function not supported yet */
  530.     }
  531.  
  532. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  533. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  534.  
  535. SocketResult MacTCPStack::DoStreamClose(Bool8 orderly) {
  536.     return(eSocketErrNoSupport); /* Function not supported yet */
  537.     }
  538.  
  539. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  540. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  541. #pragma mark -
  542.  
  543. pascal void MacTCPStack::DNRComplete(hostInfo *hInfo, Bool8 *doneFlag) {
  544.     *doneFlag = true;
  545.     }
  546.  
  547. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  548. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  549.  
  550. void MacTCPStack::UDPAsyncRead(UDPiopb *udppb) {
  551.     MacTCPStackRef stack = (MacTCPStackRef) udppb->csParam.receive.userDataPtr;
  552. #if GENERATINGCFM || __A5__
  553.     UInt32 saveA5 = SetA5(stack->homeA5);
  554. #else
  555.     UInt32 saveA4 = GetCurrentA4(stack->homeA4);
  556. #endif
  557.     SocketResult error = eSocketNoError;
  558.  
  559.     /* Parameter validation */
  560. #if (_DEBUGSAFE)
  561.     qAssertIfNull(udppb, eSocketErrInternal, kSocketErrInternalStr);
  562.     qAssertIfNull(stack, eSocketErrInternal, kSocketErrInternalStr);
  563. #endif
  564.     
  565.     /* Perform UDP Receive */
  566.     if (udppb->ioResult != connectionTerminated) {
  567. #if (_DEBUGSAFE)
  568.         qThrowIfError(udppb->ioResult, "Error Returning Buffer on UDP Stream");
  569. #endif
  570.  
  571.         udppb->ioCompletion = stack->bfrRtnUPP;
  572.         udppb->ioResult = 0;
  573.         udppb->ioCRefNum = stack->refnum;
  574.         udppb->csCode = UDPRead;
  575.         udppb->udpStream = stack->stream;
  576.         udppb->csParam.receive.timeOut = 0;
  577.         udppb->csParam.receive.remoteHost = 0;
  578.         udppb->csParam.receive.remotePort = 0;
  579.         udppb->csParam.receive.rcvBuff = 0;
  580.         udppb->csParam.receive.rcvBuffLen = 0;
  581.         udppb->csParam.receive.secondTimeStamp = 0;
  582.         udppb->csParam.receive.userDataPtr = (Ptr) stack;
  583. #if (_DEBUGSAFE)
  584.         qThrowIfError(PBControlAsync((ParmBlkPtr) udppb), 
  585.                 "Unable to Receive on UDP Stream");
  586. #else        
  587.         error = PBControlAsync((ParmBlkPtr) &udppb);
  588. #endif
  589.         }
  590.  
  591.  
  592. /* CATCH */
  593.     qCatch();
  594.  
  595. #if GENERATINGCFM || __A5__
  596.     SetA5(saveA5);
  597. #else
  598.     SetA4(saveA4);
  599. #endif
  600.     }
  601.  
  602. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  603. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  604.  
  605. void MacTCPStack::UDPAsyncBfrRtn(UDPiopb *udppb) {
  606.     MacTCPStackRef stack = (MacTCPStackRef) udppb->csParam.receive.userDataPtr;
  607. #if GENERATINGCFM || __A5__
  608.     UInt32 saveA5 = SetA5(stack->homeA5);
  609. #else
  610.     UInt32 saveA4 = GetCurrentA4(stack->homeA4);
  611. #endif
  612.     SocketResult error = eSocketNoError;
  613.  
  614.     /* Parameter validation */
  615. #if (_DEBUGSAFE)
  616.     qAssertIfNull(udppb, eSocketErrInternal, kSocketErrInternalStr);
  617.     qAssertIfNull(stack, eSocketErrInternal, kSocketErrInternalStr);
  618. #endif
  619.     
  620.     /* Implement socket callback chain */
  621.     if (! udppb->ioResult) {
  622.         SocketAddress address;
  623.         
  624.         address.type = AF_INET;
  625.         address.length = sizeof(address.buffer.tcpip);
  626.         address.buffer.tcpip.type = 2;
  627.         address.buffer.tcpip.port = udppb->csParam.receive.remotePort;
  628.         address.buffer.tcpip.host = udppb->csParam.receive.remoteHost;
  629.         memset(address.buffer.tcpip.data, 0,
  630.                 sizeof(address.buffer.tcpip.data));
  631.         
  632. #if (_DEBUGSAFE)
  633.         qThrowIfError(stack->DatagramRead(udppb->csParam.receive.rcvBuff, 
  634.                 udppb->csParam.receive.rcvBuffLen, &address), 0);
  635. #else        
  636.         stack->DatagramRead(udppb->csParam.receive.rcvBuff, 
  637.                 udppb->csParam.receive.rcvBuffLen, &address);
  638. #endif
  639.         }
  640.         
  641.     /* Perform UDP Buffer Return */
  642.     if (udppb->ioResult != connectionTerminated) {
  643. #if (_DEBUGSAFE)
  644.         qThrowIfError(udppb->ioResult, "Error Reading from UDP Stream");
  645. #endif
  646.  
  647.         udppb->ioCompletion = stack->readUPP;
  648.         udppb->ioResult = 0;
  649.         udppb->ioCRefNum = stack->refnum;
  650.         udppb->csCode = UDPBfrReturn;
  651.         udppb->udpStream = stack->stream;
  652.         udppb->csParam.receive.timeOut = 0;
  653.         udppb->csParam.receive.userDataPtr = (Ptr) stack;
  654.     #if (_DEBUGSAFE)
  655.         qThrowIfError(PBControlAsync((ParmBlkPtr) udppb), 
  656.                 "Unable to Return Buffer on UDP Stream");
  657.     #else        
  658.         error = PBControlAsync((ParmBlkPtr) &udppb);
  659.     #endif
  660.         }
  661.  
  662.     
  663. /* CATCH */
  664.     qCatch();
  665.  
  666. #if GENERATINGCFM || __A5__
  667.     SetA5(saveA5);
  668. #else
  669.     SetA4(saveA4);
  670. #endif
  671.     }
  672.  
  673. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  674. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  675.  
  676. void MacTCPStack::UDPSendComplete(UDPiopb *udppb) {
  677.     MacTCPStackRef stack = (MacTCPStackRef) udppb->csParam.send.userDataPtr;
  678. #if GENERATINGCFM || __A5__
  679.     UInt32 saveA5 = SetA5(stack->homeA5);
  680. #else
  681.     UInt32 saveA4 = GetCurrentA4(stack->homeA4);
  682. #endif
  683.     SocketResult error = eSocketNoError;
  684.     MacTCPDataPtr writeData = (MacTCPDataPtr) udppb;
  685.  
  686.     /* Parameter validation */
  687. #if (_DEBUGSAFE)
  688.     qAssertIfNull(udppb, eSocketErrInternal, kSocketErrInternalStr);
  689.     qAssertIfNull(stack, eSocketErrInternal, kSocketErrInternalStr);
  690.     qTraceIfError(udppb->ioResult, "Error Sending on UDP Stream");
  691. #endif
  692.     
  693.     /* Return the data container */
  694. #if (_DEBUGSAFE)
  695.     qThrowIfError(Dequeue((QElem *) writeData, &stack->busyQ), 
  696.             "Unable to release write buffer");
  697. #else
  698.     Dequeue((QElem *) writeData, &stack->busyQ);
  699. #endif
  700.     qEnqueue((QElem *) writeData, &stack->freeQ);
  701.  
  702.         
  703. /* CATCH */
  704.     qCatch();
  705.  
  706. #if GENERATINGCFM || __A5__
  707.     SetA5(saveA5);
  708. #else
  709.     SetA4(saveA4);
  710. #endif
  711.     }
  712.  
  713. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  714. /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
  715.  
  716. void MacTCPStack::E2SCleanup(MacTCPStackRef stack) {
  717. #if GENERATINGCFM || __A5__
  718.     UInt32 saveA5 = SetA5(stack->homeA5);
  719. #else
  720.     UInt32 saveA4 = GetCurrentA4(stack->homeA4);
  721. #endif
  722.     SocketResult error = eSocketNoError;
  723.     
  724.     if (stack && stack->stream)
  725. #if (_DEBUGSAFE)
  726.         qTraceIfError(stack->DoDispose(), 0);
  727. #else        
  728.         error = stack->DoDispose();
  729. #endif
  730.     
  731.  
  732. /* CATCH */
  733.     qCatch();
  734.  
  735. #if GENERATINGCFM || __A5__
  736.     SetA5(saveA5);
  737. #else
  738.     SetA4(saveA4);
  739. #endif
  740.     }
  741.  
  742.